package com.hisense.ovcloud.asop.service;

import com.hisense.ovcloud.asop.config.Constants;
import com.hisense.ovcloud.asop.dto.resp.ServiceLogMetricResp;
import com.hisense.ovcloud.asop.entity.ch.ServiceLogMetricBiz;
import com.hisense.ovcloud.asop.entity.ch.WifiStatus;
import com.hisense.ovcloud.asop.tools.BeanReflectUtil;
import io.r2dbc.spi.ConnectionFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 查询日志
 *
 * @author: yangweiping1
 * @description:
 * @date: 2025/3/27 13:43
 */
@Slf4j
@Service
public class CHServiceLogQueryService {


    public Mono<List<ServiceLogMetricResp>> queryMetricBizLog(String beginTime, String endTime, long durationSeconds, String service, String path, String field, String order) {
        return Mono.from(connectionFactory.create())
                .flatMapMany(conn -> {
                    String sql = Constants.SqlTemplates
                            .QUERY_SERVICE_METRIC_BIZ_LOG.replaceAll("__CONDITION__", appendCondition(service, path)).replaceAll("__ORDER__", appendOrder(field, order));
                    log.info(sql);
                    return conn.createStatement(sql)
                            .bind("queryTimeSeconds", durationSeconds)
                            .bind("beginTime", beginTime)
                            .bind("endTime", endTime)
                            .execute();
                })
                .flatMap(result -> {
                    if (result != null) {
                        return result.map((row, rowMetadata) -> {
                            try {
                                return BeanReflectUtil.ckRowToBean(ServiceLogMetricResp.class, row);
                            } catch (Exception e) {
                                log.error("failed to map row to bean {}", "ServiceLogMetricBiz");
                                throw new RuntimeException(e);
                            }
                        });
                    } else {
                        return Mono.just(ServiceLogMetricResp.builder().build());
                    }
                }).collectList();
    }

    private static String appendOrder(String field, String order) {
        StringBuilder orderBy = new StringBuilder();
        if (StringUtils.isNotBlank(field) && StringUtils.isNotBlank(order)) {
            orderBy.append(String.format(" order by %s %s", field, getColumnByField(order)));
            return orderBy.toString();
        }
        return " order by requestTotal desc ";
    }

    private static String getColumnByField(String field) {
        return switch (field) {
            case "descend" -> "desc";
            case "ascend" -> "asc";
            default -> "";
        };
    }

    private static String appendCondition(String service, String path) {
        StringBuilder condition = new StringBuilder();
        if (StringUtils.isNotBlank(service)) {
            condition.append(String.format(" and service = '%s' ", service));
        }
        if (StringUtils.isNotBlank(path)) {
            condition.append(String.format(" and multiMatchAny(path, ['%s'])", path));
        }
        return condition.toString();
    }

    private final ConnectionFactory connectionFactory;

    public CHServiceLogQueryService(ConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }
}
